package cn.mujiankeji.mbrowser.app

import android.content.Context
import android.widget.Toast
import cn.mujiankeji.mbrowser.功能.下载.下载管理器接口
import cn.mujiankeji.mbrowser.工具.mlog
import cn.mujiankeji.mbrowser.数据.配置项.应用配置
import cn.mujiankeji.mbrowser.界面.小窗页.信息窗口状态
import cn.mujiankeji.mbrowser.界面.小窗页.文本编辑窗口状态
import cn.mujiankeji.mbrowser.界面.框架.主视图.标签页状态
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.CacheMemoryStaticUtils
import com.blankj.utilcode.util.FileIOUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.koin.core.context.GlobalContext
import 操作.工具类.md5
import 操作.工具类.数值操作
import java.io.File

object 应用接口 {

    // -- 应用函数 --
    fun 注销() {
        try {
            // 清理资源
            CacheMemoryStaticUtils.clear()
            临时缓存数据.clear()
            
            // 使用ActivityUtils终止应用
            ActivityUtils.finishAllActivities()
            
            // 确保进程被终止
            android.os.Process.killProcess(android.os.Process.myPid())
        } catch (e: Exception) {
            e.printStackTrace()
            // 兜底退出方式
            System.exit(0)
        }
    }

    /**
     * 退出当前页面，不终止应用进程
     * 可用于返回上一级或关闭特定页面
     */
    fun 退出当前页面() {
        try {
            // 只关闭顶部Activity
            ActivityUtils.getTopActivity()?.finish()
        } catch (e: Exception) {
            e.printStackTrace()
            // 如果获取顶部Activity失败，尝试关闭所有Activity
            ActivityUtils.finishAllActivities(false)
        }
    }

    /**
     * 退出到主页，关闭除了主Activity以外的所有Activity
     * 适用于需要回到主页面的场景
     */
    fun 退出到主页() {
        try {
            // 获取所有Activity
            val activities = ActivityUtils.getActivityList()
            if (activities.size <= 1) {
                // 如果只有一个Activity，不需要操作
                return
            }
            
            // 保留第一个Activity（通常是主Activity），关闭其他所有Activity
            for (i in activities.size - 1 downTo 1) {
                activities[i].finish()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 检查应用是否在后台运行
     * @return 如果应用在后台运行则返回true，否则返回false
     * 
     * 注：使用 com.blankj.utilcodex:1.30.6 中的 AppUtils.isAppForeground() 方法
     */
    fun 是否在后台运行(): Boolean {
        // 使用AppUtils.isAppForeground替代ActivityUtils.isAppForeground
        return !AppUtils.isAppForeground()
    }
    
    /**
     * 将应用切换到前台
     * 如果应用在后台运行，调用此方法可将应用切换到前台
     * 
     * 注：使用 com.blankj.utilcodex:1.30.6 中的 AppUtils.launchApp() 方法
     */
    fun 切换到前台() {
        if (是否在后台运行()) {
            // 使用AppUtils提供的方法将应用切换到前台
            AppUtils.launchApp(GlobalContext.get().get<Context>().packageName)
        }
    }


    fun 加载(标签页状态: 标签页状态){
        界面模块().加载(标签页状态)
    }
    fun 搜索(关键词 : String){
        应用路由.加载(应用配置.默认搜索地址(关键词))
    }
    fun 关闭小窗(){
        界面模块().移除小窗(null)
    }
    fun 界面模块() : 界面模块 = GlobalContext.get().get<界面模块>()
    fun 安装扩展(代码或地址 : String){
        mlog("安装扩展",代码或地址)
        // 地址
        if (代码或地址.startsWith("http://") || 代码或地址.startsWith("https://")){

        }
    }
    fun 编辑窗口(默认值 : String, 编辑完成响应 : (String?) -> Unit){
        文本编辑窗口状态(默认值){
            编辑完成响应(it)
        }.显示()
    }

    /**
     * @param 取消按钮名称 若显示则设置，为空不显示
     */
    fun 信息框(内容 : String,
                 确认按钮名称 : String = "确定",
                 取消按钮名称 : String?= null,
             响应 : (Boolean) -> Unit)
    {
        信息窗口状态(内容,确认按钮名称,取消按钮名称,响应).显示()

    }

    /**
     * 显示或隐藏全局加载中界面
     * @param 显示 是否显示加载中界面
     * @param 提示文本 加载中的提示文本，可选
     */
    fun 显示加载中界面(显示: Boolean, 提示文本: String = "") {
        val 界面模块 = GlobalContext.get().get<界面模块>()
        界面模块.显示加载中界面 = 显示
        if (显示 && 提示文本.isNotEmpty()) {
            界面模块.加载中提示文本 = 提示文本
        }
    }

    suspend fun 下载( url: String,
              文件名: String,
              目标路径: String = 应用配置.路径_下载,
              请求头: Map<String, String>? = null,
              userAgent: String? = null){
        withContext(Dispatchers.IO){
            GlobalContext.get().get<下载管理器接口>()
                .请求新下载(url,文件名,目标路径,请求头,userAgent)
        }
    }
    suspend fun 请求下载(地址 : String,名称 : String?){

    }

    fun 输出提示(str : String){
        Toast.makeText(GlobalContext.get().get<Context>(),str,Toast.LENGTH_SHORT).show()
    }


    // -- 缓存 --

    /**
     * 第二个值为存储位置，默认会先存储到内存并返回数据，最后在后台中写入文件删掉内存，true=内存，false硬盘
     */
    val 临时缓存数据 = HashMap<String,Boolean>()

    /**
     * 临时tmp 避免全部数据加入到内存导致崩溃
     * putTmp 返回sign
     */
    fun 写缓存(v : String) : String{
        生成临时缓存文件名(v).let { name ->

            // 为了能够迅速返回 不占用时间，先存到内存并回调sign
            CacheMemoryStaticUtils.put(name,v).let {
                // 如果文件长度大于 1000 就将数据写到文件中
                临时缓存数据.put(name,true)

                try {
                    FileIOUtils.writeFileFromString(应用配置.路径_缓存 + name,v)
                    CacheMemoryStaticUtils.remove(name)
                    临时缓存数据.remove(name)
                }catch (e:java.lang.Exception){

                }


            }
            return name
        }


    }
    fun 生成临时缓存文件名(v : String):String{
        var sign = "tmp_" + ("v" + v.length + System.nanoTime()).md5()
        while (临时缓存数据.containsKey(sign)) {
            sign = "tmp_" + ("66" + v.length + System.nanoTime() + 数值操作.随机数(0,555)).md5()
        }
        return sign
    }
    fun 取缓存(sign : String) : String{
        if (sign.length != 36 ) return sign
        if (临时缓存数据.containsKey(sign) && 临时缓存数据.get(sign) == true) return CacheMemoryStaticUtils.get(sign)
        return if (sign.startsWith("tmp_") && File(应用配置.路径_缓存 +sign).isFile) FileIOUtils.readFile2String(
            应用配置.路径_缓存 +sign) ?: sign
        else sign
    }
    fun 删除缓存(sign : String) {
        if (临时缓存数据.containsKey(sign) && 临时缓存数据.get(sign) == true) CacheMemoryStaticUtils.remove(sign)
    }



}